use anyhow::Result;
use serde::{Deserialize, Serialize};
use serde_json;

// use crate::mod_stor::osfiles::csvs_gw::CSVGW;
use crate::mod_stor::osqlite::os_sqlx::tab_auth::AuthOption;
// use crate::mod_stor::osqlite::os_sqlx::tab_user::UserOption;
use crate::mod_stor::osqlite::os_sqlx::tab_userconf::UconfOption;
use crate::mod_stor::osqlite::os_sqlx::OSqliteMan;

#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct AppConfig {
    pub auto_launch: bool,
    pub silent_launch: bool,
    pub language: String,
    pub theme: String,
    pub log_list: Vec<String>,
}

#[derive(Debug, Clone)]
pub struct OStor {
    mu_sql: OSqliteMan,
}

impl OStor {
    pub async fn new() -> Result<Self> {
        let mu_sql = OSqliteMan::init("MU_VER1.0.0.db").await?;
        let ostor = OStor { mu_sql };
        Ok(ostor)
    }

    pub async fn get_auth(self, u_id: Option<i32>, auth_name: &str) -> Result<Option<String>> {
        let sql: OSqliteMan = self.mu_sql.clone();
        let auth = AuthOption {
            user_id: u_id,
            auth_name: Some(auth_name.to_string()),
            content: None,
        };
        let content = sql.read_auth(auth).await?;
        Ok(content)
    }

    pub async fn set_auth(self, u_id: Option<i32>, auth_name: &str, content: String) -> Result<()> {
        let sql: OSqliteMan = self.mu_sql.clone();
        let auth = AuthOption {
            user_id: u_id,
            auth_name: Some(auth_name.to_string()),
            content: Some(content),
        };
        sql.save_auth(auth).await?;
        Ok(())
    }

    pub async fn get_conf(self, user_id: i32, conf: &str, ver: &str) -> Result<Option<String>> {
        let sql: OSqliteMan = self.mu_sql.clone();
        let uconf = UconfOption {
            user_id: Some(user_id),
            conf_id: sql.clone().get_conf_id(conf.to_string()).await?,
            version: Some(ver.to_string()),
            content: None,
        };
        let content = sql.read_user_conf(uconf).await?;
        Ok(content)
    }

    pub async fn set_conf(self, user_id: i32, conf: &str, ver: &str, cont: String) -> Result<()> {
        let sql: OSqliteMan = self.mu_sql.clone();
        let uconf = UconfOption {
            user_id: Some(user_id),
            conf_id: sql.clone().get_conf_id(conf.to_string()).await?,
            version: Some(ver.to_string()),
            content: Some(cont),
        };
        sql.save_user_conf(uconf).await?;
        Ok(())
    }
}

#[tauri::command]
pub async fn get_app_conf_cmd() -> AppConfig {
    if let Ok(ostor) = OStor::new().await {
        if let Ok(Some(content)) = ostor.get_conf(1, "app_conf_v1", "default").await {
            if let Ok(conf) = serde_json::from_str::<AppConfig>(&content) {
                return conf;
            }
        }
    }
    return AppConfig::default();
}

#[tauri::command]
pub async fn set_app_conf_cmd(app_conf: AppConfig) -> String {
    if let (Ok(ostor), Ok(content)) = (OStor::new().await, serde_json::to_string(&app_conf)) {
        if let Ok(()) = ostor.set_conf(1, "app_conf_v1", "default", content).await {
            return "[set_app_conf_cmd] successful!!!".to_string();
        }
    }
    println!("[set_app_conf_cmd] fail...");
    return "[set_app_conf_cmd] fail...".to_string();
}

